package com.wgcloud.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wgcloud.CommonConfig;
import com.wgcloud.OshiUtil;
import com.wgcloud.RestUtil;
import com.wgcloud.ScheduledTask;
import com.wgcloud.aop.CustomLog;
import com.wgcloud.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/appInfo")
public class AppInfo {
    @Autowired
    private CommonConfig commonConfig;
    @Autowired
    private RestUtil restUtil;


    @GetMapping("/clearCache")
    public Result<Object> clearCache() {
        // 清空数据
        // System.out.println("开始清除进程信息");
        ScheduledTask.appInfoList.clear();
        // System.out.println("结束进程信息");
        // 返回一个json响应
        return Result.success("移除进程信息成功");
    }

    // 立即同步一次最新的进程信息
    @GetMapping("/syncProcess")
    public Result<Object> syncProcess() {
        try {
            JSONObject paramsJson = new JSONObject();
            paramsJson.put("hostname", commonConfig.getBindIp());
            String resultJson = restUtil.post(commonConfig.getServerUrl() + "/wgcloud/appInfo/agentList", paramsJson);
            if (resultJson != null) {
                JSONArray resultArray = JSONUtil.parseArray(resultJson);
                log.info("主动获取监控的进程信息：共计 {} 个--{}", resultArray.size(), resultJson);
                // JSONArray resultArray = JSONUtil.parseArray(resultJson);
                ScheduledTask.appInfoList.clear();
                if (!resultArray.isEmpty()) {
                    ScheduledTask.appInfoList = JSONUtil.toList(resultArray, com.wgcloud.entity.AppInfo.class);
                }
            } else {
                log.error("立即同步进程发生异常: 获取监控的进程信息为空");
                return Result.error(500, "获取监控的进程信息为空");
            }
        } catch (Exception e) {
            log.error("立即同步进程发生异常: ", e);
            return Result.error(500, "立即同步进程发生异常: " + e.getMessage());
        }
        return Result.success("立即同步进程成功");
    }

    // 获取进程的执行路径信息和命令行信息
    @PostMapping("/getAppPath")
    public Result<Object> getAppPath(@RequestBody Map<String, Object> appInfo) {
        try {
            Map<String, String> result = new java.util.HashMap<>(Collections.emptyMap());
            // 接受一个json格式的参数，包含appPid和hostname
            // 从appInfo中获取appPid和hostname
            String appPid = (String) appInfo.get("appPid");
            String appName = (String) appInfo.get("appName");
            // 获取appPath
            String appPath = OshiUtil.getAppPath(appName, appPid);
            if (appPath != null && !appPath.isEmpty()) {
                result.put("appPath", appPath);
            } else {
                result.put("appPath", "未找到执行路径");
            }
            // 获取进程的命令行
            String appCommandLine = OshiUtil.getAppCommandLine(appName, appPid);
            if (appCommandLine != null && !appCommandLine.isEmpty()) {
                result.put("appCommandLine", appCommandLine);
            } else {
                result.put("appCommandLine", "未找到命令行");
            }
            return Result.success(result);

        } catch (Exception e) {
            log.error("getAppPath路由获取进程的执行路径信息和命令行发生异常: ", e);
            return null;
        }
    }

    // 根据应用名称和执行文件路径获取进程号
    @PostMapping("/getAppPid")
    public Result<Object> getAppPid(@RequestBody Map<String, Object> appInfo) {
        try {
            // 接受一个json格式的参数，包含appName和appPath
            // 从appInfo中获取appName和appPath
            String appName = (String) appInfo.get("appName");
            String appPath = (String) appInfo.get("appPath");
            if (Objects.equals(appPath, "未找到执行路径")) {
                appPath = "";
            }
            // 获取进程号命令行
            String appCommandLine = (String) appInfo.get("appCommandLine");
            if (Objects.equals(appCommandLine, "未找到命令行")) {
                appCommandLine = "";
            }
            // 根据应用名称/命令行和执行文件路径获取进程号
            String appPid = OshiUtil.getProcessIdByNameAndPath(appName, appPath, appCommandLine);
            if (appPid != null) {
                return Result.success(appPid);
            }
            log.warn("未能通过应用名称/命令行和执行文件路径获取到进程号: appName={}, appPath={},appCommandLine={}", appName, appPath, appCommandLine);
            return null;
        } catch (Exception e) {
            log.error("getAppPid路由根据应用名称和执行文件路径获取进程号发生异常: ", e);
            return Result.error(500, "getAppPid路由根据应用名称和执行文件路径获取进程号发生异常: " + e.getMessage());
        }
    }

    // 定义 GET 接口，接收 hostName 和 appName 参数（可选）
    @CustomLog
    @GetMapping("/getProcessInfo")
    public Result<Object> getInfo(
            @RequestParam(name = "appName", required = false) String appName,
            @RequestParam(name = "hostName", required = false) String hostName,
            @RequestParam(name = "appPath", required = false) String appPath
    ) {
        // 如果参数为空，可以设置默认值或返回空字符串
        // hostName = (hostName != null) ? hostName : "localhost";
        // appName = (appName != null) ? appName : "defaultAppNameDef";
        // System.out.println(appName);
        try {
            ArrayList<Map<String, Object>> result = OshiUtil.getAllProcessesInfo(appName, hostName, appPath);
            return Result.success(result);
        } catch (Exception e) {
            log.error("getProcessInfo路由获取进程信息发生异常: ", e);
            return Result.error(500, "/getProcessInfo路由获取进程信息发生异常: " + e.getMessage());
        }
    }

}
